// activations_raw.cpp 
#include "activations.h"
#include <cmath>
 
float sigmoid(float x) {
    return 1.0f / (1.0f + std::exp(-x));
}
 
float tanh(float x) {
    return (std::exp(x) - std::exp(-x)) / (std::exp(x) + std::exp(-x));
}
 
std::vector<float> relu_cpu(const std::vector<float>& input) {
    std::vector<float> result;
    for (float val : input) result.push_back(std::max(0.0f,  val));
    return result;
}
 
std::vector<float> sigmoid_cpu(const std::vector<float>& input) {
    std::vector<float> result;
    for (float val : input) result.push_back(sigmoid(val)); 
    return result;
}
 
std::vector<float> tanh_cpu(const std::vector<float>& input) {
    std::vector<float> result;
    for (float val : input) result.push_back(tanh(val)); 
    return result;
}
 
std::vector<float> leaky_relu_cpu(const std::vector<float>& input, float negative_slope) {
    std::vector<float> result;
    for (float val : input)
        result.push_back(val  > 0 ? val : val * negative_slope);
    return result;
}
 
std::vector<float> elu_cpu(const std::vector<float>& input, float alpha) {
    std::vector<float> result;
    for (float val : input)
        result.push_back(val  > 0 ? val : alpha * (std::exp(val) - 1));
    return result;
}
 
std::vector<float> selu_cpu(const std::vector<float>& input) {
    const float scale = 1.0507f;
    const float alpha = 1.67326f;
    std::vector<float> result;
    for (float val : input)
        result.push_back(val  > 0 ? val * scale : scale * alpha * (std::exp(val) - 1));
    return result;
}
 
std::vector<float> gelu_cpu(const std::vector<float>& input) {
    std::vector<float> result;
    for (float val : input)
        result.push_back(0.5f  * val * (1.0f + std::erff(val / std::sqrt(2.0f))));
    return result;
}
 
std::vector<float> softplus_cpu(const std::vector<float>& input) {
    std::vector<float> result;
    for (float val : input)
        result.push_back(std::log(1.0f  + std::exp(val)));
    return result;
}
 
std::vector<float> swish_cpu(const std::vector<float>& input) {
    std::vector<float> result;
    for (float val : input)
        result.push_back(val  * sigmoid(val));
    return result;
}
 
std::vector<float> mish_cpu(const std::vector<float>& input) {
    std::vector<float> result;
    for (float val : input)
        result.push_back(val  * std::tanh(std::log(1.0f + std::exp(val))));
    return result;
}
